home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / DEMOS / BLA2SRC.ZIP / CONVCMF.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-02-12  |  12.2 KB  |  432 lines

  1.  
  2. USES Objects, Dos, HexConversions;
  3.  
  4.  
  5. TYPE
  6.   TBuf = ARRAY[0..65520] OF BYTE;
  7. CONST
  8.   SizeMusic : WORD  = 0;
  9.   Music     : ^TBuf = NIL;
  10.   DBcol     : BYTE  = 48;
  11.  
  12.  
  13. PROCEDURE PutByte(VAR f: TEXT; b: BYTE);
  14.   BEGIN
  15.     Music^[SizeMusic] := b;
  16.     INC(SizeMusic);
  17.   END;
  18.  
  19.  
  20. PROCEDURE PutByteFile(VAR f: TEXT; b: BYTE);
  21.   BEGIN
  22.     IF DBcol = 48 THEN
  23.       BEGIN
  24.         WriteLn(f);
  25.         Write(f, '    DB ');
  26.         DBcol := 1;
  27.       END
  28.     ELSE IF DBcol <> 0 THEN
  29.       Write(f, ',');
  30.  
  31.     inc (DBcol);
  32.     Write(f, '0', HexByte(b), 'h');
  33.   END;
  34.  
  35.  
  36.  
  37. VAR
  38.   St       : TBufStream;
  39.   f        : TEXT;
  40.   s        : STRING;
  41.   v, r, p  : WORD;
  42.   vl       : WORD;
  43.   i, j, k  : WORD;
  44.   time,
  45.   otime,
  46.   ntime,
  47.   delta, dl: LONGINT;
  48.   change   : BOOLEAN;
  49.   buf      : ARRAY[1..256] OF BYTE;
  50.   Patches  : ARRAY[0..15] OF BYTE;
  51.   ChPatch  : ARRAY[0..8] OF BYTE;
  52.   Volumes  : ARRAY[0..8] OF BYTE;
  53.   Channels : ARRAY[0..8] OF LONGINT;
  54.  
  55.   Midi     : ARRAY[0..15,1..4] OF BYTE;
  56.  
  57.   KeyOn    : ARRAY[0..8] OF RECORD
  58.                               ins,
  59.                               freq,
  60.                               vol   : BYTE;
  61.                             END;
  62.   KeyOff   : ARRAY[0..8] OF BOOLEAN;
  63.  
  64. LABEL
  65.   Fin;
  66.  
  67. BEGIN
  68.  
  69.   New(Music);
  70.  
  71.   FOR i := 0 TO  8 DO ChPatch[i] := i;
  72.   FOR i := 0 TO 15 DO Patches[i] := i;
  73.  
  74.   FillChar(Volumes,  SizeOf(Volumes),    0);
  75.   FillChar(Channels, SizeOf(Channels),   0);
  76.   FillChar(Midi,     SizeOf(Midi),     255);
  77.  
  78.   St.Init(ParamStr(1), stOpenRead, 16384);
  79.   Assign(f, ParamStr(2));
  80.   Rewrite(f);
  81.  
  82.   WriteLn(f, '; --------------------------------');
  83.   WriteLn(f, '; Converted CMF File: '+ParamStr(1));
  84.   WriteLn(f, '; (C) 1994 bye JCAB/VangeliSTeam');
  85.   WriteLn(f);
  86.   WriteLn(f, '; === Instruments');
  87.  
  88.   v := 0;
  89.   St.Seek(36);
  90.   St.Read(v, 1);
  91.   STR(v, s);
  92.   WriteLn(f);
  93.   WriteLn(f, 'CMF_NInstruments = ', s);
  94.  
  95.   St.Seek(6);
  96.   St.Read(r, 2);
  97.   St.Seek(r);
  98.   WriteLn(f);
  99.   WriteLn(f, 'CMF_Instruments:');
  100.   FOR i := 1 TO v DO
  101.     BEGIN
  102.       St.Read(buf, 16);
  103.       Write(f, '    DB ');
  104.       FOR j := 1 TO 11 DO
  105.         BEGIN
  106.           Write(f, '0', HexByte(buf[j]), 'h');
  107.           IF j < 11 THEN
  108.             Write(f, ', ')
  109.           ELSE
  110.             WriteLn(f);
  111.         END;
  112.     END;
  113.  
  114.   WriteLn(f);
  115.   WriteLn(f, '; === Data');
  116.  
  117.   St.Seek(8);
  118.   St.Read(v, 2);
  119.   St.Seek(v);
  120.   time := 0;
  121.   otime := 0;
  122.   WHILE St.Status = stOk DO
  123.     BEGIN
  124.  
  125. IF time = 6 THEN
  126.       delta := 0;
  127.       delta := 0;
  128.       r     := 0;
  129.       REPEAT
  130.         dl := 0;
  131.         REPEAT
  132.           St.Read(r, 1);
  133.           IF St.Status <> stOk THEN GOTO Fin;
  134.           dl := 128*dl + (r AND $7F);
  135.         UNTIL (r AND $80) = 0;
  136.         delta := delta + dl;
  137.  
  138.         St.Read(r, 1);
  139.         IF r < $80 THEN
  140.           BEGIN
  141.             r := v;
  142.             St.Seek(St.GetPos-1);
  143.           END;
  144.         IF ((r AND $F0) = $D0) THEN
  145.           BEGIN
  146.             St.Read(r, 1);
  147.             r := 0;
  148.           END
  149.         ELSE IF ((r AND $F0) = $B0) THEN
  150.           BEGIN
  151.             St.Read(r, 1);
  152.             St.Read(r, 1);
  153.             r := 0;
  154.           END
  155.  
  156.       UNTIL r <> 0;
  157.       v := r;
  158.  
  159.       INC(time, delta);
  160.       ntime := time+3 - ((time+3) MOD 6);
  161.       delta := (ntime - otime) DIV 6;
  162.  
  163.       IF delta > 0 THEN
  164.         BEGIN
  165.           otime := ntime;
  166.           IF delta > 15 THEN
  167.             BEGIN
  168.               PutByte(f, $E0+((delta-1) SHR 8));
  169.               PutByte(f, (delta-1) AND 255);
  170.             END
  171.           ELSE
  172.             PutByte(f, $D0+delta-1);
  173.         END;
  174.  
  175.       IF v = 255 THEN GOTO Fin;
  176.  
  177.       CASE v AND $F0 OF
  178.         $80: BEGIN
  179.  
  180.                r := 0;
  181.                St.Read(r, 1);
  182.                IF ((v AND 15) = 0) OR TRUE THEN
  183.                  BEGIN
  184.                    p := 0;
  185.                    FOR i := 0 TO 8 DO
  186.                      IF Midi[v AND 15][i] = r THEN
  187.                        BEGIN
  188.                          Midi[v AND 15][i] := 255;
  189.                          p := i;
  190.                          i := 8;
  191.                        END;
  192.                    PutByte(f, $90+p);
  193.                  END;
  194.                Channels[p] := time;
  195.                St.Read(vl, 1);
  196.              END;
  197.         $90: BEGIN
  198.                j := time+1;
  199.                p := 0;
  200.                IF ((v AND 15) = 0) OR TRUE THEN
  201.                  BEGIN
  202.                    FOR i := 0 TO 8 DO
  203.                      BEGIN
  204.                        IF (time+1 > Channels[i]) AND
  205.                           (Patches[v AND 15] = ChPatch[i]) THEN
  206.                          BEGIN
  207.                            j := time+1;
  208.                            FOR i := i TO 8 DO
  209.                              IF (j > Channels[i]) AND
  210.                                 (Patches[v AND 15] = ChPatch[i]) THEN
  211.                                BEGIN
  212.                                  j := Channels[i];
  213.                                  p := i;
  214.                                END;
  215.                          END
  216.                        ELSE
  217.                          IF j > Channels[i] THEN
  218.                            BEGIN
  219.                              j := Channels[i];
  220.                              p := i;
  221.                            END;
  222.                      END;
  223. {                   p := v AND 15;}
  224.                    Channels[p] := $7FFFFFF;
  225.                    IF Patches[v AND 15] = ChPatch[p] THEN
  226.                      PutByte(f, (p SHL 4))
  227.                    ELSE
  228.                      BEGIN
  229.                        PutByte(f, (p SHL 4)+Patches[v AND 15]+1);
  230.                        Volumes[p] := 255;
  231.                        ChPatch[p] := Patches[v AND 15];
  232.                      END;
  233.                    r := 0;
  234.                    St.Read(r, 1);
  235.                    Midi[v AND 15][p] := r;
  236.                    vl := 0;
  237.                    St.Read(vl, 1);
  238.                    vl := vl + $80 + $08;
  239.                    IF vl > 255 THEN vl := 255;
  240.                    vl := vl AND $F0;
  241.                    vl := $FE;
  242.                    IF (vl <> Volumes[p]) {OR TRUE} THEN
  243.                      BEGIN
  244.                        PutByte(f, r+$80);
  245.                        IF vl > 0 THEN
  246.                          PutByte(f, vl)
  247.                        ELSE
  248.                          PutByte(f, 0);
  249.                      END
  250.                    ELSE
  251.                      PutByte(f, r);
  252.                    Volumes[p] := vl;
  253.                  END
  254.                ELSE
  255.                  BEGIN
  256.                    St.Read(r,  1);
  257.                    St.Read(vl, 1);
  258.                  END;
  259.              END;
  260.         $C0: BEGIN
  261.                r := 0;
  262.                St.Read(r, 1);
  263.                Patches[v AND 15] := r;
  264.              END;
  265.         $D0: BEGIN
  266.                r := 0;
  267.                St.Read(r, 1);
  268.              END;
  269.       ELSE
  270.           WriteLn('ORROR. Comando: ', v);
  271.           WriteLn('Offset: ', St.GetPos);
  272.           WriteLn('Time: ', time);
  273.           WriteLn('Delta: ', delta);
  274.           HALT(1);
  275.       END;
  276.  
  277.     END;
  278.  
  279. Fin:
  280.   PutByte(f, $FF);
  281.  
  282.   FOR k := 0 TO 3 DO
  283.     BEGIN
  284.       WriteLn(f);
  285.       Write  (f, 'CMF_Data', k, ':');
  286.  
  287.       FillChar(KeyOn,  SizeOf(KeyOn),  255);
  288.       FillChar(KeyOff, SizeOf(KeyOff),   0);
  289.       delta := 0;
  290.       time  := 0;
  291.       FOR i := 0 TO SizeMusic-1 DO
  292.         BEGIN
  293.           v := Music^[i] SHR 4;
  294.           r := Music^[i] AND 15;
  295.           CASE v OF
  296.             0..8: BEGIN
  297.                     KeyOn[v].ins  := r;
  298.                     KeyOn[v].freq := Music^[i+1];
  299.                     IF (Music^[i+1] AND $80) <> 0 THEN
  300.                       BEGIN
  301.                         KeyOn[v].vol := Music^[i+2];
  302.                         INC(i);
  303.                       END;
  304.                     INC(i);
  305.                     IF k <> ChPatch[v] THEN KeyOn[v].ins := 255;
  306.                   END;
  307.             9:    KeyOff[r] := TRUE;
  308.             $D,
  309.             $E,
  310.             $F:
  311.                   BEGIN
  312.                     change := FALSE;
  313.                     FOR j := 0 TO 8 DO
  314.                       IF KeyOn[j].ins < 255 THEN
  315.                         change := TRUE;
  316.  
  317.                     IF change OR (v = $F) THEN
  318.                       BEGIN
  319.                         DBcol := 48;
  320.                         IF time DIV 32 < (time+delta) DIV 32 THEN
  321.                           BEGIN
  322.                             dl := time+delta;
  323.                             dl := (dl - dl MOD 32) - time;
  324.                             IF dl > 16 THEN
  325.                               BEGIN
  326.                                 PutByteFile(f, $E0+((dl-1) SHR 8));
  327.                                 PutByteFile(f, (dl-1) AND 255);
  328.                               END
  329.                             ELSE
  330.                               BEGIN
  331.                                 PutByteFile(f, $D0+dl-1);
  332.                                 Write(f, '     ');
  333.                               END;
  334.                             time  := time  + dl;
  335.                             delta := delta - dl;
  336.                             WriteLn(f);
  337.  
  338.                             DBcol := 48;
  339.                           END;
  340.                         IF delta = 0 THEN
  341.                           BEGIN
  342.                             WriteLn(f);
  343.                             Write(f, '    DB           ');
  344.                             DBcol := 0;
  345.                           END;
  346.                         IF delta > 0 THEN
  347.                           BEGIN
  348.                             IF delta > 16 THEN
  349.                               BEGIN
  350.                                 PutByteFile(f, $E0+((delta-1) SHR 8));
  351.                                 PutByteFile(f, (delta-1) AND 255);
  352.                               END
  353.                             ELSE
  354.                               BEGIN
  355.                                 PutByteFile(f, $D0+delta-1);
  356.                                 Write(f, '     ');
  357.                               END;
  358.                           END;
  359.                         time  := time + delta;
  360.                         delta := 0;
  361.                       END;
  362.  
  363.                     IF change THEN
  364.                       BEGIN
  365.     {
  366.                         FOR j := 0 TO 8 DO
  367.                           IF KeyOff[j] AND (KeyOn[j].ins = 255) THEN
  368.                             BEGIN
  369.                               PutByteFile(f, $90+j);
  370.                             END;
  371.     }
  372.                         FOR j := 0 TO 8 DO
  373.                           IF KeyOn[j].ins < 255 THEN
  374.                             BEGIN
  375.                               PutByteFile(f, (j SHL 4) + KeyOn[j].ins);
  376.                               PutByteFile(f, KeyOn[j].freq);
  377.                               IF (KeyOn[j].freq AND $80) <> 0 THEN
  378.                                 PutByteFile(f, KeyOn[j].vol)
  379.                               ELSE
  380.                                 Write(f, '     ');
  381.                             END
  382.                           ELSE
  383.                             Write(f, '               ');
  384.                       END;
  385.  
  386.                     FillChar(KeyOn,  SizeOf(KeyOn),  255);
  387.                     FillChar(KeyOff, SizeOf(KeyOff),   0);
  388.  
  389.                     IF (v = $D) OR (v = $E) THEN
  390.                       BEGIN
  391.                         WHILE (v = $D) OR (v = $E) OR (v = $9) DO
  392.                           BEGIN
  393.                             IF v = $D THEN
  394.                               INC(delta, r+1)
  395.                             ELSE IF v = $E THEN
  396.                               BEGIN
  397.                                 INC(i);
  398.                                 INC(delta, r*256+Music^[i]+1);
  399.                               END;
  400.  
  401.                             INC(i);
  402.                             v := Music^[i] SHR 4;
  403.                             r := Music^[i] AND 15;
  404.                           END;
  405.                         DEC(i);
  406.                       END
  407.                     ELSE IF v = $F THEN
  408.                       BEGIN
  409.                         DBcol := 48;
  410.                         PutByteFile(f, $FF);
  411.                       END;
  412.                   END;
  413.           END;
  414.         END;
  415.  
  416.       WriteLn(f);
  417.       WriteLn(f);
  418.  
  419.     END;
  420.  
  421.   WriteLn(f);
  422.   WriteLn(f);
  423.   WriteLn(f, 'CMF_Offsets:');
  424.  
  425.   FOR k := 0 TO 3 DO
  426.     WriteLn(f, '    DW 1, OFFSET CMF_Data', k, ', OFFSET CMF_Data', k);
  427.  
  428.   Close(f);
  429.   St.Done;
  430.  
  431. END.
  432.